const timeExp = /\[(\d{2,}):(\d{2})(?:\.(\d{2,3}))?]/g

const STATE_PAUSE = 0
const STATE_PLAYING = 1

export default class Lyric {
  constructor(lrc, hanlder = () => { }) {
    this.lrc = lrc
    this.lines = []
    this.handler = hanlder
    this.state = STATE_PAUSE
    this.curNum = 0
    this.current = 0
    this.initLines()
  }

  initLines () {
    const lines = this.lrc.split('\n')
    for (let i = 0; i < lines.length; i++) {
      const line = lines[i]
      let result = timeExp.exec(line)
      if (result) {
        const txt = line.replace(timeExp, '').trim()
        if (txt) {
          this.lines.push({
            time: (result[1] * 60 * 1000 + result[2] * 1000 + (result[3] || 0) * 10 - 10) / 1000,
            txt
          })
        }
      }
    }
    this.lines.sort((a, b) => {
      return a.time - b.time
    })
  }

  length () {
    return this.lines.length
  }

  findCurNum (time) {
    if (time <= this.current) {
      return this.curNum
    }

    const length = this.length()
    for (let i = this.curNum; i < length; i++) {
      if (time <= this.lines[i].time) {
        this.current = this.lines[i].time
        return i
      }
    }
    return length
  }

  clearCache () {
    this.curNum = 0
    this.current = 0
  }

  callHandler (i) {
    if (i < 0) {
      return
    }
    this.handler({
      txt: this.lines[i].txt,
      lineNum: i
    })
  }

  play (startTime = 0) {
    if (!this.lines.length) {
      return
    }
    this.state = STATE_PLAYING
    const curNum = this.findCurNum(startTime)
    if (curNum === this.curNum) {
      return
    }
    this.curNum = curNum

    this.callHandler(this.curNum - 1)
  }

  stop () {
    this.state = STATE_PAUSE
  }

  seek (offset) {
    this.play(offset)
  }
}
